

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
  <link rel="icon" href="/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="Moe Wang">
  <meta name="keywords" content="">
  
    <meta name="description" content="原理  代码转换：typeScript编译成JavaScript、scss，less编译成css 文件优化：压缩JavaScript、html、css文件，压缩合并图片等 代码分割：提供多个页面的公共代码，抽离首屏不需要的代码使其异步加载 模块合并：模块化的项目里会有很多模块和文件，构建狗能把模块分类合并 自动刷新：监听本地源代码，自动重构刷新浏览器 扩展性好，插件机制完善  打包过程  利用ba">
<meta property="og:type" content="article">
<meta property="og:title" content="webpack总结">
<meta property="og:url" content="https://moewang0321.github.io/2020/02/24/2020-02-24-webpack%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE/index.html">
<meta property="og:site_name" content="moe_大杂烩">
<meta property="og:description" content="原理  代码转换：typeScript编译成JavaScript、scss，less编译成css 文件优化：压缩JavaScript、html、css文件，压缩合并图片等 代码分割：提供多个页面的公共代码，抽离首屏不需要的代码使其异步加载 模块合并：模块化的项目里会有很多模块和文件，构建狗能把模块分类合并 自动刷新：监听本地源代码，自动重构刷新浏览器 扩展性好，插件机制完善  打包过程  利用ba">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2020/1/10/16f8ccdeb77f673c?imageView2/0/w/1280/h/960/format/webp/ignore-error/1">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2020/1/10/16f8ccdec2f9318d?imageView2/0/w/1280/h/960/format/webp/ignore-error/1">
<meta property="article:published_time" content="2020-02-24T02:14:21.000Z">
<meta property="article:modified_time" content="2023-02-14T08:07:21.208Z">
<meta property="article:author" content="Moe Wang">
<meta property="article:tag" content="webpack">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://user-gold-cdn.xitu.io/2020/1/10/16f8ccdeb77f673c?imageView2/0/w/1280/h/960/format/webp/ignore-error/1">
  
  
  
  <title>webpack总结 - moe_大杂烩</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"moewang0321.github.io","root":"/","version":"1.9.4","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 5.4.2"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>moe_大杂烩</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                <span>首页</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                <span>归档</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                <span>分类</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                <span>标签</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                <span>关于</span>
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              <i class="iconfont icon-search"></i>
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">
              <i class="iconfont icon-dark" id="color-toggle-icon"></i>
            </a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/default.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="webpack总结"></span>
          
        </div>

        
          
  <div class="mt-3">
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2020-02-24 10:14" pubdate>
          2020年2月24日 上午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          8.4k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          70 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">webpack总结</h1>
            
            
              <div class="markdown-body">
                
                <h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><hr>
<ul>
<li>代码转换：<code>typeScript</code>编译成<code>JavaScript</code>、<code>scss，less</code>编译成<code>css</code></li>
<li>文件优化：压缩<code>JavaScript</code>、<code>html</code>、<code>css</code>文件，压缩合并图片等</li>
<li>代码分割：提供多个页面的公共代码，抽离首屏不需要的代码使其异步加载</li>
<li>模块合并：模块化的项目里会有很多模块和文件，构建狗能把模块分类合并</li>
<li>自动刷新：监听本地源代码，自动重构刷新浏览器</li>
<li>扩展性好，插件机制完善</li>
</ul>
<h2 id="打包过程"><a href="#打包过程" class="headerlink" title="打包过程"></a>打包过程</h2><hr>
<ol>
<li>利用babel完成代码转换，生成单个文件依赖</li>
<li>从入口开始分析，生成依赖图谱</li>
<li>将引用模块打包为立即执行函数</li>
<li>把最终的bundle文件写入bundle.js里</li>
</ol>
<h2 id="四大核心"><a href="#四大核心" class="headerlink" title="四大核心"></a>四大核心</h2><hr>
<ul>
<li>entry：入口，即js入口源文件</li>
<li>output：生成文件</li>
<li>loader：文件处理</li>
<li>plugins：插件</li>
</ul>
<h2 id="Entry"><a href="#Entry" class="headerlink" title="Entry"></a>Entry</h2><p>webpack应该用哪个模块作为入口文件，作为构建内部依赖图的开始，进入入口后，webpack会找到哪些库和模块是入口依赖的，并随即被处理，最后输出到bundle.js的文件中</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//单入口：entry是一个字符串</span><br><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = &#123;<br>  <span class="hljs-attr">entry</span>: <span class="hljs-string">&#x27;./src/index.js&#x27;</span><br>&#125;<br><span class="hljs-comment">//多入口：entry是一个对象</span><br><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = &#123;<br>  <span class="hljs-attr">entry</span>: <span class="hljs-string">&#x27;./src/index.js&#x27;</span><br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="Output"><a href="#Output" class="headerlink" title="Output"></a>Output</h2><hr>
<p>告诉webpack在哪输出bundles，以及怎么命名他，在配置文件中均可搞定</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//单入口配置项</span><br><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = &#123;<br>    <span class="hljs-attr">entry</span>: <span class="hljs-string">&#x27;./src/index.js&#x27;</span>,<br>    <span class="hljs-attr">output</span>: &#123;<br>        <span class="hljs-attr">filename</span>: <span class="hljs-string">&#x27;bundle.js’,</span><br><span class="hljs-string">        path: __dirname + &#x27;</span>/dist<span class="hljs-string">&#x27;</span><br><span class="hljs-string">    &#125;</span><br><span class="hljs-string">&#125;;</span><br><span class="hljs-string">//多入口配置项</span><br><span class="hljs-string">module.exports = &#123;</span><br><span class="hljs-string">  entry: &#123;</span><br><span class="hljs-string">    app: &#x27;</span>./src/app.<span class="hljs-property">js</span><span class="hljs-string">&#x27;,</span><br><span class="hljs-string">    search: &#x27;</span>./src/search.<span class="hljs-property">js</span><span class="hljs-string">&#x27;</span><br><span class="hljs-string">  &#125;,</span><br><span class="hljs-string">  output: &#123;</span><br><span class="hljs-string">    filename: &#x27;</span>[name].<span class="hljs-property">js</span><span class="hljs-string">&#x27;,//[name]占位符确保文件名唯一</span><br><span class="hljs-string">    path: __dirname + &#x27;</span>/dist<span class="hljs-string">&#x27;</span><br><span class="hljs-string">  &#125;</span><br><span class="hljs-string">&#125;</span><br><span class="hljs-string"></span><br></code></pre></td></tr></table></figure>

<h2 id="Loader"><a href="#Loader" class="headerlink" title="Loader"></a>Loader</h2><hr>
<p><code>loader</code>让webpack能够处理非<code>javaScript</code>文件，因为webpack自己只能看懂<code>javaScript</code>。<code>loader</code>能够把所有类型的文件转换成webpack能够处理的模块，然后利用打包能力对他进行处理</p>
<h3 id="Loader的特点"><a href="#Loader的特点" class="headerlink" title="Loader的特点"></a>Loader的特点</h3><ul>
<li>每一个loader的职责都是单一的，只能完成一种转换</li>
<li>loader本质上是node.js模块，这个模块需要导出一个函数</li>
<li>loader总是从右到左被调用</li>
</ul>
<h3 id="常用Loader"><a href="#常用Loader" class="headerlink" title="常用Loader"></a>常用Loader</h3><h4 id="处理样式"><a href="#处理样式" class="headerlink" title="处理样式"></a>处理样式</h4><ul>
<li><code>css-loader</code>加载css文件</li>
<li><code>style-loader</code>使用style标签把<code>css-loader</code>内部样式注入到html中</li>
<li><code>less-loader,sass-loader</code>解析css预处理器</li>
</ul>
<h4 id="处理js"><a href="#处理js" class="headerlink" title="处理js"></a>处理js</h4><p>让我们能够使用最新的js代码（ES6，ES7等）及让我们能够使用基于js进行了拓展的语言，比如JSX等</p>
<h4 id="处理文件"><a href="#处理文件" class="headerlink" title="处理文件"></a>处理文件</h4><p>通常使用的两种loader是<code>file-loader</code>和<code>url-loader</code>，两者主要的区别是<code>url-loader</code>能够设置图片的大小限制，如果大小超过限制，则行为等同于<code>file-loader</code>，如果图片大小不超过限制，那么图片会以base64的形式打包</p>
<h4 id="处理vue单文件"><a href="#处理vue单文件" class="headerlink" title="处理vue单文件"></a>处理vue单文件</h4><p><code>vue-loader</code>是webpack的加载器魔铠，它让我们的随心所欲的编写<code>.vue</code>格式的单文件组件。<code>vue-loader</code> 模块允许 <code>webpack</code> 使用单独的加载器模块（例如 <code>sass 或 scss 加载器</code>）提取和处理每个部分。该设置使我们可以使用 <code>.vue</code> 文件无缝编写程序。</p>
<p><strong>在文章最后，我们会尝试开发一个简易的loader来加深我们的理解</strong></p>
<h3 id="Plugin"><a href="#Plugin" class="headerlink" title="Plugin"></a>Plugin</h3><hr>
<p>专注于处理webpack在编译过程里某个特定任务的功能模块</p>
<h3 id="特点"><a href="#特点" class="headerlink" title="特点"></a>特点</h3><ul>
<li><p>是一个独立的模块</p>
</li>
<li><p>模块对外暴露一个js函数</p>
</li>
<li><p>函数的原型 <code>(prototype)</code> 上定义了一个注入 <code>compiler</code> 对象的 <code>apply</code>方法 <code>apply</code> 函数中需要有通过 <code>compiler</code> 对象挂载的 <code>webpack</code> 事件钩子，钩子的回调中能拿到当前编译的 <code>compilation</code> 对象，如果是异步编译插件的话可以拿到回调 <code>callback</code></p>
</li>
<li><p>完成自定义自编程流程并处理<code>complition</code>对象的内部数据</p>
</li>
<li><p>如果异步编译插件的话，数据处理完成后执行<code>callback</code>回调</p>
</li>
</ul>
<h3 id="常用Plugin"><a href="#常用Plugin" class="headerlink" title="常用Plugin"></a>常用Plugin</h3><ul>
<li><code>HotModuleReplacementPlugin</code> 代码热替换。因为 <code>Hot-Module-Replacement</code> 的热更新是依赖于 <code>webpack-dev-server</code>，后者是在打包文件改变时更新打包文件或者 reload 刷新整个页面，<code>HRM</code> 是只更新修改的部分。</li>
<li><code>HtmlWebpackPlugin</code>, 生成 html 文件。将 webpack 中<code>entry</code>配置的相关入口 chunk 和 <code>extract-text-webpack-plugin</code>抽取的 css 样式 插入到该插件提供的<code>template</code>或者<code>templateContent</code>配置项指定的内容基础上生成一个 html 文件，具体插入方式是将样式<code>link</code>插入到<code>head</code>元素中，<code>script</code>插入到<code>head</code>或者<code>body</code>中。</li>
<li><code>ExtractTextPlugin</code>, 将 css 成生文件，而非内联 。该插件的主要是为了抽离 css 样式,防止将样式打包在 js 中引起页面样式加载错乱的现象。</li>
<li><code>NoErrorsPlugin</code>报错但不退出 webpack 进程</li>
<li><code>UglifyJsPlugin</code>，代码丑化，开发过程中不建议打开。 <code>uglifyJsPlugin</code> 用来对 js 文件进行压缩，从而减小 js 文件的大小，加速 load 速度。<code>uglifyJsPlugin</code> 会拖慢 webpack 的编译速度，所有建议在开发简单将其关闭，部署的时候再将其打开。多个 html 共用一个 js 文件(chunk)，可用 <code>CommonsChunkPlugin</code></li>
<li><code>purifycss-webpack</code> 。打包编译时，可剔除页面和 js 中未被使用的 css，这样使用第三方的类库时，只加载被使用的类，大大减小 css 体积</li>
<li><code>optimize-css-assets-webpack-plugin</code>  压缩 css，优化 css 结构，利于网页加载和渲染</li>
<li><code>webpack-parallel-uglify-plugin</code>  可以并行运行 UglifyJS 插件，这可以有效减少构建时间</li>
</ul>
<p><strong>同样的，文章最后我们也会尝试开发一个Plugin</strong></p>
<h2 id="webpack配置"><a href="#webpack配置" class="headerlink" title="webpack配置"></a>webpack配置</h2><hr>
<h3 id="1、Webpack-项目初始化"><a href="#1、Webpack-项目初始化" class="headerlink" title="1、Webpack 项目初始化"></a>1、Webpack 项目初始化</h3><p><strong>1、新建 Web 项目</strong></p>
<p>新建一个目录，再进入项目根目录执行 npm init 来初始化最简单的采用了模块化开发的项目；最终生成 package.json 文件；</p>
<figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs coffeescript">$ <span class="hljs-built_in">npm</span> init<br>复制代码<br></code></pre></td></tr></table></figure>

<p><strong>2、安装 Webpack 到本项目</strong></p>
<p>（1）查看 Webpack 版本</p>
<p>运行以下命令可以查看 Webpack 的版本号</p>
<figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs coffeescript">$ <span class="hljs-built_in">npm</span> view webpack versions<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（2）安装 Webpack</p>
<p>可以选择（1）步骤罗列得到的 Webpack 版本号，也可以安装最新稳定版、最新体验版本，相关命令如下所示，我选择安装 4.28.2 版本（没有为什么，就想装个 4.x 的版本）；</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-regexp">//</span> 安装指定版本<br>npm i -D webpack@<span class="hljs-number">4.28</span>.<span class="hljs-number">2</span><br><br><span class="hljs-regexp">//</span> 安装最新稳定版<br>npm i -D webpack<br><br><span class="hljs-regexp">//</span> 安装最新体验版本<br>npm i -D webpack@beta<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（3）安装 Webpack 脚手架</p>
<p>需要安装 Webpack 脚手架，才能在命令窗口执行 Webpack 命令，运行以下命令安装 Webpack 脚手架；</p>
<figure class="highlight avrasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs avrasm">$ npm i -D webpack-<span class="hljs-keyword">cli</span><br>复制代码<br></code></pre></td></tr></table></figure>

<p><strong>3、使用 Webpack</strong></p>
<p>使用 Webpack 构建一个采用 CommonJS 模块化编写的项目；</p>
<p>（1）新建页面入口文件 index.html</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;en&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;viewport&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">&quot;X-UA-Compatible&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;ie=edge&quot;</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Webpack<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!--导入 Webpack 输出的 JavaScript 文件--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;./dist/bundle.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>  <br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br>复制代码<br></code></pre></td></tr></table></figure>

<p>（2）新建需要用到的 JS 文件</p>
<p>show.js 文件</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs dart"><span class="hljs-comment">// 操作 DOM 元素，把 content 显示到网页上</span><br>function <span class="hljs-keyword">show</span>(content) &#123;<br>  <span class="hljs-built_in">window</span>.<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">&#x27;app&#x27;</span>).innerText = <span class="hljs-string">&#x27;Hello,&#x27;</span> + content;<br>&#125;<br><br><span class="hljs-comment">// 通过 CommonJS 规范导出 show 函数</span><br>module.exports = <span class="hljs-keyword">show</span>;<br>复制代码<br></code></pre></td></tr></table></figure>

<p>main.js 文件</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs dart"><span class="hljs-comment">// 通过 CommonJS 规范导入 show 函数</span><br><span class="hljs-keyword">const</span> <span class="hljs-keyword">show</span> = require(<span class="hljs-string">&#x27;./show.js&#x27;</span>);<br><span class="hljs-comment">// 执行 show 函数</span><br><span class="hljs-keyword">show</span>(<span class="hljs-string">&#x27;Webpack&#x27;</span>);<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（3）新建 Webpack 配置文件 webpack.config.js</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs awk">const path = require(<span class="hljs-string">&#x27;path&#x27;</span>);<br><br>module.exports = &#123;<br>  <span class="hljs-regexp">//</span> JavaScript 执行入口文件<br>  entry: <span class="hljs-string">&#x27;./main.js&#x27;</span>,<br>  output: &#123;<br>    <span class="hljs-regexp">//</span> 把所有依赖的模块合并输出到一个 bundle.js 文件<br>    filename: <span class="hljs-string">&#x27;bundle.js&#x27;</span>,<br>    <span class="hljs-regexp">//</span> 输出文件都放到 dist 目录下<br>    path: path.resolve(__dirname, <span class="hljs-string">&#x27;./dist&#x27;</span>),<br>  &#125;<br>&#125;;<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（4）执行 webpack 命令进行构建</p>
<p>在 package.json 文件中配置编译命令，如下所示：</p>
<figure class="highlight 1c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs 1c">  <span class="hljs-string">&quot;scripts&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;build&quot;</span>: <span class="hljs-string">&quot;webpack --config webpack.config.js&quot;</span>,<br>  &#125;,<br>复制代码<br></code></pre></td></tr></table></figure>

<p>执行以下命令进行项目的 Webpack 编译，成功后会在项目根目录下生成编译目录 dist ；</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs routeros">$ npm <span class="hljs-built_in">run</span> build<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（5）运行 index.html</p>
<p>编译成功后，我们用浏览器打开 index.html 文件，能看到页面成功显示 “Hello Webpack”；</p>
<h3 id="2、Loader-配置"><a href="#2、Loader-配置" class="headerlink" title="2、Loader 配置"></a>2、Loader 配置</h3><p>本节通过为之前的例子添加样式，来尝试使用 Loader；</p>
<p>（1）新建样式文件 main.css</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-id">#app</span>&#123;<br>  <span class="hljs-attribute">text-align</span>: center;<br>  <span class="hljs-attribute">color</span>:<span class="hljs-string">&#x27;#999&#x27;</span>;<br>&#125;<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（2）将 main.css 文件引入入口文件 main.js 中，如下所示：</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-regexp">//</span> 通过 CommonJS 规范导入 CSS 模块<br>require(<span class="hljs-string">&#x27;./main.css&#x27;</span>);<br><br><span class="hljs-regexp">//</span> 通过 CommonJS 规范导入 show 函数<br>const show = require(<span class="hljs-string">&#x27;./show.js&#x27;</span>);<br><span class="hljs-regexp">//</span> 执行 show 函数<br>show(<span class="hljs-string">&#x27;Webpack&#x27;</span>);<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（3）Loader 配置</p>
<p>以上修改后去执行 Webpack 构建是会报错的，因为 Webpack 不原生支持解析 CSS 文件。要支持非 JavaScript 类型的文件，需要使用 Webpack 的 Loader 机制；</p>
<p>（3.1）运行以下命令，安装 style-loader 和 css-loader，其中：</p>
<ul>
<li>css-loader 用于读取 CSS 文件；</li>
<li>style-loader 把 CSS 内容注入到 JavaScript 中；</li>
</ul>
<figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs coffeescript">$ <span class="hljs-built_in">npm</span> i -D style-loader css-loader<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（3.2）进行以下配置</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs awk">module:&#123;<br>rules:[<br>  &#123;<br>	<span class="hljs-regexp">//</span> 用正则去匹配要用该 loader 转换的 CSS 文件<br>	test:<span class="hljs-regexp">/\.css$/</span>,<br>	use:[<span class="hljs-string">&#x27;style-loader&#x27;</span>,<span class="hljs-string">&#x27;css-loader&#x27;</span>]<br>  &#125;<br> ]<br>&#125;<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（4）查看结果</p>
<p>编译后，刷新 index.html ，查看刚刚的样式 loader 已经起作用；</p>
<p><img src="https://user-gold-cdn.xitu.io/2020/1/10/16f8ccdeb77f673c?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" srcset="/img/loading.gif" lazyload alt="1"></p>
<h3 id="3、Plugin-配置"><a href="#3、Plugin-配置" class="headerlink" title="3、Plugin 配置"></a>3、Plugin 配置</h3><p>（1）安装样式提取插件  extract-text-webpack-plugin</p>
<figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs coffeescript">$ <span class="hljs-built_in">npm</span> i -D extract-text-webpack-plugin@next<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（2）plugin 文件配置如下</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs css">  module:&#123;<br>    rules:[<br>      &#123;<br>        // 用正则去匹配要用该 loader 转换的 CSS 文件<br>        test:/\.css$/,<br>        use:ExtractTextPlugin.<span class="hljs-built_in">extract</span>(&#123;<br>          use:[<span class="hljs-string">&#x27;css-loader&#x27;</span>]<br>        &#125;),<br>      &#125;<br>    ]<br>  &#125;,<br>  plugins:[<br>    new <span class="hljs-built_in">ExtractTextPlugin</span>(&#123;<br>       // 从 <span class="hljs-selector-class">.js</span> 文件中提取出来的 <span class="hljs-selector-class">.css</span> 文件的名称<br>       filename:`[name]_[hash:<span class="hljs-number">8</span>].css`<br>    &#125;),<br>  ]<br>复制代码<br></code></pre></td></tr></table></figure>

<p>（3）查看结果</p>
<p>通过以上配置后，执行 Webapack 的执行命令，发现在 dist 目录下，生成对应的 css 文件；存在的坑点：</p>
<ul>
<li>我们需要手动将生成的 css 文件引入到 index.html 中；</li>
<li>修改 css 文件后，会生成新的 css 文件，原先的不会删除；</li>
</ul>
<h3 id="4、使用-DevServer"><a href="#4、使用-DevServer" class="headerlink" title="4、使用 DevServer"></a>4、使用 DevServer</h3><p>（1）执行以下命令安装 webpack-dev-server</p>
<figure class="highlight axapta"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs axapta">$ npm i -D  webpack-dev-<span class="hljs-keyword">server</span><br>复制代码<br></code></pre></td></tr></table></figure>

<p>在 package.json 中配置启动命令</p>
<figure class="highlight 1c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs 1c">  <span class="hljs-string">&quot;scripts&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;build&quot;</span>: <span class="hljs-string">&quot;webpack --config webpack.config.js&quot;</span>,<br>    <span class="hljs-string">&quot;dev&quot;</span>: <span class="hljs-string">&quot;webpack-dev-server&quot;</span>,<br>  &#125;,<br>复制代码<br></code></pre></td></tr></table></figure>

<p>运行命令后，就可以启动 HTTP 服务</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs routeros">$ npm <span class="hljs-built_in">run</span> dev<br>复制代码<br></code></pre></td></tr></table></figure>

<p>启动结果如下所示，我们可以通过 <a target="_blank" rel="noopener" href="http://localhost:8080/">http://localhost:8080/</a>  访问我们的 index.html 的demo</p>
<p><img src="https://user-gold-cdn.xitu.io/2020/1/10/16f8ccdec2f9318d?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" srcset="/img/loading.gif" lazyload alt="1"></p>
<p>（2）实时预览</p>
<p>我们在运行命令后面添加参数 –watch 实现实时预览，配置如下所示：</p>
<figure class="highlight 1c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs 1c">  <span class="hljs-string">&quot;scripts&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;dev&quot;</span>: <span class="hljs-string">&quot;webpack-dev-server --watch&quot;</span><br>  &#125;,<br>复制代码<br></code></pre></td></tr></table></figure>

<p>然后我们修改 main.js 的传入参数，发现并不能实时预览，也没有报错！！！ why?</p>
<p>踩坑：</p>
<p>在 index.html 中需要将 js 的路径修改为：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;bundle.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>  <br>复制代码<br></code></pre></td></tr></table></figure>

<p>而不能是之前的（因为这个是编译生成的，并不是通过 devServer 生成放在内存的）</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;./dist/bundle.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <br>复制代码<br></code></pre></td></tr></table></figure>

<p>（3）模块热替换</p>
<p>可以通过配置  – hot  进行模块热替换；</p>
<h2 id="番外"><a href="#番外" class="headerlink" title="番外"></a>番外</h2><hr>
<p>没错，文章最后了，现在我们开始开发一个<code>loader</code>和<code>plugin</code></p>
<h3 id="开发一个loader"><a href="#开发一个loader" class="headerlink" title="开发一个loader"></a>开发一个<code>loader</code></h3><p>需求：开发一个<code>loader</code>，将KobeBryant<code>转换为</code>mamba forever`。</p>
<h4 id="1-编写loader"><a href="#1-编写loader" class="headerlink" title="1.编写loader"></a>1.编写loader</h4><p>新建目录<code>my-loader</code>作为名字，执行<code>npm init -y</code>快速创建一个模块化项目，然后新建<code>index.js</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">content</span>) &#123;<br>	<span class="hljs-keyword">return</span> content &amp;&amp; content.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/KobeBryant/gi</span> , <span class="hljs-string">&#x27;mamba forever&#x27;</span>)<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="2-注册模块"><a href="#2-注册模块" class="headerlink" title="2.注册模块"></a>2.注册模块</h4><p>一般情况下，我们需要的loader都是利用npm安装，但是我们可以使用<code>npm link</code>命令，以求在不发布模块的情况下，将本地的源码链接到项目的<code>node_modules</code>下。在项目的根目录下执行以下命令</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs powershell">λ npm link my<span class="hljs-literal">-loader</span><br></code></pre></td></tr></table></figure>

<h4 id="3-在webpack中配置loader"><a href="#3-在webpack中配置loader" class="headerlink" title="3.在webpack中配置loader"></a>3.在webpack中配置loader</h4><p>在<code>webpack.base.config.js</code>中加上以下配置</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js">&#123;<br>	<span class="hljs-attr">test</span>:<span class="hljs-regexp">/\.js/</span>,<br>	<span class="hljs-attr">loader</span>:<span class="hljs-string">&#x27;my-loader&#x27;</span><br>&#125;<br></code></pre></td></tr></table></figure>

<p>这样我们js里所有的字符串<code>KobeBryant</code>就会替换为<code>mamba forever</code>了</p>
<h4 id="4-配置参数"><a href="#4-配置参数" class="headerlink" title="4.配置参数"></a>4.配置参数</h4><p>前面我们是写死的替换，如果我们想要通过配置项来进行改变怎么办</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// index.js</span><br><span class="hljs-keyword">var</span> utils = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;loader-utils&#x27;</span>)<br><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">content</span>) &#123;<br>    <span class="hljs-keyword">const</span> options = utils.<span class="hljs-title function_">getOptions</span>(<span class="hljs-variable language_">this</span>)<br>    <span class="hljs-keyword">return</span> content &amp;&amp; content.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/KobeBryant/gi</span> , options.<span class="hljs-property">name</span>)<br>&#125;<br><br><span class="hljs-comment">// webpack.base.conf.js</span><br>&#123;<br>  <span class="hljs-attr">test</span>:<span class="hljs-regexp">/\.js/</span>,<br>  <span class="hljs-attr">use</span>: &#123;<br>    <span class="hljs-attr">loader</span>: <span class="hljs-string">&#x27;my-loader&#x27;</span>,<br>    <span class="hljs-attr">options</span>: &#123;<br>      <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;KobeBryant&#x27;</span>,<br>    &#125;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="开发一个Plugin"><a href="#开发一个Plugin" class="headerlink" title="开发一个Plugin"></a>开发一个Plugin</h3><ul>
<li>webpack在编译中，会广播很多事件</li>
<li>webpack应用了观察者模式，插件可以监听webpack事件来触发对应的处理逻辑</li>
<li>插件中可以使用webpack的api</li>
</ul>
<h4 id="1-编写插件"><a href="#1-编写插件" class="headerlink" title="1.编写插件"></a>1.编写插件</h4><p>创建目录<code>my-plugin</code>作为编写的插件，执行<code>npm init -y</code>快速创建一个模块化项目，然后新建<code>index.js</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">MyPlugin</span> &#123;<br>	<span class="hljs-title function_">constructor</span>(<span class="hljs-params">doneCakkback , failCallback</span>) &#123;<br>		<span class="hljs-comment">//保存在创建实例时候传入的回调函数</span><br>        <span class="hljs-variable language_">this</span>.<span class="hljs-property">doneCallback</span> = doneCallback<br>        <span class="hljs-variable language_">this</span>.<span class="hljs-property">failCallback</span> = failCallback<br>	&#125;<br>    <br>    <span class="hljs-title function_">apply</span>(<span class="hljs-params">compiler</span>) &#123;<br>        <span class="hljs-comment">//成功完成一次完整的编译和输出时，会触发done</span><br>        compile.<span class="hljs-title function_">plugin</span>(<span class="hljs-string">&#x27;done&#x27;</span> , <span class="hljs-function"><span class="hljs-params">stats</span> =&gt;</span> &#123;<br>            <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">doneCallback</span>(stats)<br>        &#125;)<br>        <br>        <span class="hljs-comment">//出现异常的时候，触发fail</span><br>        compiler.<span class="hljs-title function_">plugin</span>(<span class="hljs-string">&#x27;fail&#x27;</span> , <span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> &#123;<br>            <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">failCallback</span>(err)<br>        &#125;)<br>    &#125;<br>&#125;<br><br><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = <span class="hljs-title class_">MyPlugin</span><br></code></pre></td></tr></table></figure>

<h4 id="2-注册模块-1"><a href="#2-注册模块-1" class="headerlink" title="2.注册模块"></a>2.注册模块</h4><p>同样的，我们link一下，以便于我们能直接使用本地的模块</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs powershell">λ npm link my<span class="hljs-literal">-plugin</span><br></code></pre></td></tr></table></figure>

<h4 id="3-配置插件"><a href="#3-配置插件" class="headerlink" title="3.配置插件"></a>3.配置插件</h4><p>在<code>webpack.base.conf.js</code>加上以下配置</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-attr">plugins</span>: [<br>	<span class="hljs-keyword">new</span> <span class="hljs-title class_">MyPlugin</span>(<br>    	<span class="hljs-function"><span class="hljs-params">stats</span> =&gt;</span> &#123;<br>            <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;编译成功&#x27;</span>)<br>        &#125;，<br>        err =&gt; &#123;<br>        	<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">&#x27;编译失败&#x27;</span>)<br>        &#125;<br>    )<br>]<br></code></pre></td></tr></table></figure>


                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/categories/webpack/" class="category-chain-item">webpack</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/tags/webpack/">#webpack</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>webpack总结</div>
      <div>https://moewang0321.github.io/2020/02/24/2020-02-24-webpack基本配置/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>Moe Wang</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2020年2月24日</div>
        </div>
      
      
      
        <div class="license-meta-item">
          <div>许可协议</div>
          <div>
            
              
              
                <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
                  <span class="hint--top hint--rounded" aria-label="BY - 署名">
                    <i class="iconfont icon-by"></i>
                  </span>
                </a>
              
            
          </div>
        </div>
      
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2020/07/10/2020-07-10-%E8%87%AA%E5%AE%9A%E4%B9%89windows%E7%BB%88%E7%AB%AF/" title="自定义一个windows终端吧">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">自定义一个windows终端吧</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2020/02/20/2020-02-20-%E5%85%B3%E4%BA%8EFetch/" title="Fetch也有坑！">
                        <span class="hidden-mobile">Fetch也有坑！</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
  
  
    <article id="comments" lazyload>
      
    <div id="giscus" class="giscus"></div>
    <script type="text/javascript">
      Fluid.utils.loadComments('#giscus', function() {
        var options = {"repo":"moewang0321/moewang0321.github.io","repo-id":"MDEwOlJlcG9zaXRvcnkyMDEyNDI0NTY=","category":"Show and tell","category-id":"DIC_kwDOC_63WM4CUMsH","theme-light":"light_protanopia","theme-dark":"dark_dimmed","mapping":"pathname","reactions-enabled":1,"emit-metadata":1,"input-position":"top","loading":"lazy","lang":"zh-CN"};
        var attributes = {};
        for (let option in options) {
          if (!option.startsWith('theme-')) {
            var key = option.startsWith('data-') ? option : 'data-' + option;
            attributes[key] = options[option];
          }
        }
        var light = 'light_protanopia';
        var dark = 'dark_dimmed';
        window.GiscusThemeLight = light;
        window.GiscusThemeDark = dark;
        attributes['data-theme'] = document.documentElement.getAttribute('data-user-color-scheme') === 'dark' ? dark : light;
        for (let attribute in attributes) {
          var value = attributes[attribute];
          if (value === undefined || value === null || value === '') {
            delete attributes[attribute];
          }
        }
        var s = document.createElement('script');
        s.setAttribute('src', 'https://giscus.app/client.js');
        s.setAttribute('crossorigin', 'anonymous');
        for (let attribute in attributes) {
          s.setAttribute(attribute, attributes[attribute]);
        }
        var ss = document.getElementsByTagName('script');
        var e = ss.length > 0 ? ss[ss.length - 1] : document.head || document.documentElement;
        e.parentNode.insertBefore(s, e.nextSibling);
      });
    </script>
    <noscript>Please enable JavaScript to view the comments</noscript>


    </article>
  


          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header">
    <i class="iconfont icon-list"></i>
    <span>目录</span>
  </p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
    </div>
  
  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init(Object.assign({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      scrollSmooth    : true,
      includeTitleTags: true,
      headingsOffset  : -boardTop,
    }, CONFIG.toc));
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }

    Fluid.events.registerRefreshCallback(function() {
      if ('tocbot' in window) {
        tocbot.refresh();
        var toc = jQuery('#toc');
        if (toc.length === 0 || !tocbot) {
          return;
        }
        if (toc.find('.toc-list-item').length > 0) {
          toc.css('visibility', 'visible');
        }
      }
    });
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.11/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));

    Fluid.events.registerRefreshCallback(function() {
      if ('anchors' in window) {
        anchors.removeAll();
        var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
        var res = [];
        for (var item of el) {
          res.push('.markdown-body > ' + item.trim());
        }
        if (CONFIG.anchorjs.placement === 'left') {
          anchors.options.class = 'anchorjs-link-left';
        }
        anchors.add(res.join(', '));
      }
    });
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/js/local-search.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
